package com.hellohoper.assembly.common.utils.serialize.hessian;


import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
import com.caucho.hessian.io.SerializerFactory;
import com.hellohoper.assembly.common.utils.SerializationException;
import com.hellohoper.assembly.common.utils.serialize.Serializer;
import org.apache.commons.codec.binary.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class Hessian2Serializer implements Serializer {

    private static final byte[] EMPTY_ARRAY = new byte[0];

    private static final SerializerFactory _serializerFactory = new SerializerFactory();

    private final static Hessian2Serializer INST = new Hessian2Serializer();

    private Hessian2Serializer() {
    }

    public Object deserializeByte(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        ByteArrayInputStream is = new ByteArrayInputStream(bytes);
        Hessian2Input hi = new Hessian2Input(is);
        hi.setSerializerFactory(_serializerFactory);
        Object obj = null;
        try {
            obj = hi.readObject();
        } catch (IOException e) {
            e.printStackTrace();
            throw new SerializationException("Could not read hessian2: " + e.getMessage(), e);
        } finally {
            try {
                is.close();
                hi.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return obj;
    }

    public byte[] serializeByte(Object t) throws SerializationException {
        if (t == null) {
            return EMPTY_ARRAY;
        }
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        Hessian2Output h2out = new Hessian2Output(bout);
        h2out.setSerializerFactory(_serializerFactory);
        byte[] bytes = null;
        try {
            h2out.writeObject(t);
            h2out.flush();
            bytes = bout.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw new SerializationException("Could not write hessian2: " + e.getMessage(), e);
        } finally {
            try {
                bout.close();
                h2out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;

    }

    public Object deserialize(String content) throws SerializationException {
        byte[] hessian2Bytes = Base64.decodeBase64(content);
        return deserializeByte(hessian2Bytes);
    }

    public String serialize(Object t) throws SerializationException {
        byte[] hessian2Bytes = serializeByte(t);
        return Base64.encodeBase64String(hessian2Bytes);
    }

    public final static Serializer getInstance() {
        return INST;
    }


}
